package com.Service.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.lang.reflect.Modifier;

/**
 * MyAdvice 类提供了四种切面增强功能，分别在目标方法执行前、抛出异常时、执行后以及返回结果后执行特定逻辑。
 *
 * @author Cheng-02
 * @version V1.0
 * @Package com.Service.advice
 * @date 2024/4/23 下午9:28
 */
@Component
@Aspect
public class MyAdvice {




    /*
    * todo:切点表达式
    *    固定语法：execution(1.2.3.4.5(6))
    *    1.访问修饰符
    *      public / private
    *    2.方法的返回参数类型
    *      String int void
    *     如果不考虑服务修饰符和返回值。两个整合一起写成 *
    *    如果不考虑，必须两个都不考虑，不允许 *String
    *   3.包的位置
    *     具体包：com.Service.Impl.Calculator1PureImpl
    *     单层模糊：com.Service.Impl.*     ：  *是单层模糊
    *     多层模糊：com..impl     ..是任意层的模糊
    *     细节：  ..不能开头
    *     找所有的imp包下的类 ：  com..impl  不能写..impl
    *   4.类的名称
    *     具体：calculatorPureImpl
    *     模糊：*
    *     不分模糊：*Impl
    *   5.方法名：语法和类名一致
    *   6.()形参数列表
    *       没有参数：()
    *       有具体参数：(String)
    *       模糊参数：(..)
    *       不分模糊：(String..)
    *               (..int) 最后一个参数是int
    *               (String..int)
    *
    *
    *
    * TODO：切点表达式的提取和复用
    *    1.当前类中 提取
    *      定义一个空方法
    *      注解 @Pointcut()
    *      在增强注解中引用切点表达式的方法即可
    *    2.创建一个存储切点的类，单独
    * */
    /**
     * 在目标方法执行前执行的增强方法。
     *
     * @param joinPoint 切点，提供访问被通知对象的方法、参数等信息。
     */


    @Before("com.Service.pointcu.MyPintCut.pc()")
    public void before(JoinPoint joinPoint) {
        // 获取方法的访问修饰符
        int modifiers = joinPoint.getSignature().getModifiers();
        String string = Modifier.toString(modifiers);

        // 获取方法所属类的简单名称
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();

        // 获取方法名
        String name = joinPoint.getSignature().getName();

        // 获取目标方法参数
        Object[] args = joinPoint.getArgs();
    }

    /**
     * 当目标方法抛出异常时执行的增强方法。
     *
     * @param joinPoint 切点，提供访问被通知对象的方法信息。
     */
    @AfterThrowing("execution(* com..Impl.*.*(..))" )
    public void afterRunning(JoinPoint joinPoint) {
        System.out.println("方法抛出异常结束了");
    }

    /**
     * 当目标方法执行完成后执行的增强方法（无论方法执行是否成功）。
     *
     * @param joinPoint 切点，提供访问被通知对象的方法信息。
     */
    @After("execution(* com..Impl.*.*(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("方法执行结束后");
    }

    /**
     * 当目标方法正常返回时执行的增强方法。
     *
     * @param joinPoint 切点，提供访问被通知对象的方法信息。
     * @param result    目标方法的返回值。
     */
    @AfterReturning(value = "execution(* com..Impl.*.*(..))", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("方法正常返回结束了");
    }
}
